# -*- coding: utf-8 -*-
import time
import math
import numpy as np
from AssetAllocation.Markowitz import Markowitz
from FinancialAlgorithmService import Common as common 
from AssetAllocation.Common import *
import AssetAllocation.BlackLitterman as BL1
import AssetAllocation.BlackLittermanIndividual as BL2


covariance_matrix = np.array([[ 9.80431914e-08,  1.78843716e-07,  7.56865614e-06,
     1.02603746e-07, -4.10268076e-06],
   [ 1.78843716e-07,  1.73766527e-04, -1.25661386e-03,
     1.86112503e-04, -1.95163973e-04],
   [ 7.56865614e-06, -1.25661386e-03,  5.32449244e-02,
     8.11113815e-03,  2.28700200e-03],
   [ 1.02603746e-07,  1.86112503e-04,  8.11113815e-03,
     2.95062334e-02,  1.80105811e-03],
   [-4.10268076e-06, -1.95163973e-04,  2.28700200e-03,
     1.80105811e-03,  2.91943169e-02]])

view_Q=[4.10959E-05,0.000172727272727273,0.00126363636363636,-0.00165528697995243,0.000470200210448071]
view_confidence = [4.10959e-05, 8.45833006707193e-06, 0.000176022628443205, 0.000412440838003013, -0.00148422000445359]
view_weight_P = [[1.0, 0, 0, 0, 0], [0, 1.0, 0, 0, 0], [0, 0, 1.0, 0, 0], [0, 0, 0, 1.0, 0], [0, 0, 0, 0, 1.0]]
market_weights = [0.2, 0.2, 0.25, 0.1, 0.25]
lambda_market =1
lambda_user = 2.5
tau_odds = [0.5, 0.5, 0.5, 0.5, 0.5]
risk_free_rate = 0


instrument_list = [{'symbol': 'CN6112.SZ', 'instrumentType': 'CURRENCY'}, {'symbol': 'H11001.CSI', 'instrumentType': 'BOND'}, {'symbol': '000300.SH', 'instrumentType': 'STOCK'}, {'symbol': 'NHAUI.SL', 'instrumentType': 'COMMODITY'}, {'symbol': 'SPX.GI', 'instrumentType': 'OVERSEA'}]
symbol_constraints = [{'symbol': 'CN6112.SZ', 'minWeight': 0.024462871026284194, 'maxWeight': 0.3424969012819506}, {'symbol': 'H11001.CSI', 'minWeight': 0.04892574205256839, 'maxWeight': 0.43562422532048767}, {'symbol': '000300.SH', 'minWeight': 0.08118477668724633, 'maxWeight': 0.510939436698781}, {'symbol': 'NHAUI.SL', 'minWeight': 0.08118477668724633, 'maxWeight': 0.16437577467951237}, {'symbol': 'SPX.GI', 'minWeight': 0.0, 'maxWeight': 0.0}]


def Run_BL1():

    optimize_objective = "MAXUSERUTILITY"
    instrument_list = [{'symbol': 'CN6112.SZ', 'instrumentType': 'CURRENCY'}, {'symbol': 'H11001.CSI', 'instrumentType': 'BOND'}, {'symbol': '000300.SH', 'instrumentType': 'STOCK'}, {'symbol': 'NHAUI.SL', 'instrumentType': 'COMMODITY'}, {'symbol': 'SPX.GI', 'instrumentType': 'OVERSEA'}]
    symbol_constraints = [{'symbol': 'CN6112.SZ', 'minWeight': 0.024462871026284194, 'maxWeight': 0.3424969012819506}, {'symbol': 'H11001.CSI', 'minWeight': 0.04892574205256839, 'maxWeight': 0.43562422532048767}, {'symbol': '000300.SH', 'minWeight': 0.08118477668724633, 'maxWeight': 0.510939436698781}, {'symbol': 'NHAUI.SL', 'minWeight': 0.08118477668724633, 'maxWeight': 0.16437577467951237}, {'symbol': 'SPX.GI', 'minWeight': 0.0, 'maxWeight': 0.0}]

    instrument_type_constraints = None
    optimize_target_volatility = None
    optimize_target_return = None

    bl = BL1.BlackLitterman(covariance_matrix=covariance_matrix,
                            view_list_Q=view_Q,
                            view_confidence=view_confidence,
                            view_weight_matrix_P=view_weight_P,
                            omega_market=market_weights,
                            lambda_market=lambda_market,
                            lambda_user=lambda_user,
                            tau_odds=tau_odds,
                            risk_free_rate=risk_free_rate)

    # common.Process_Contrains(instrument_list, symbol_constraints, instrument_type_constraints, bl)
    optimal_weights = bl.optimize()
    print(optimal_weights)


def Run_BL2():

    userParamJson = {
        'mortagageAmt': 0,  #
        'monthSpend': 0,  # 月总支出 外部传参
        'liquidity': 0,  # 流动性变动项mortgage + parents * 500 + children * 1000
        'Pmt': 0,  # 白条/金条当月应还总额
        'liabilityAsset': 0,  # 负债率
        'monthIncome': 0,  # 月总收入
        'asset_investable': 20000,  # 用户可投资金
        'totalAssetAmt': 0,  # 用户持仓金额
        'fixAsset': 0,  # 定期持仓总金额
        'lambda_i': 6.5,  # 单位风险要求的收益报酬。换算得到的风评指标float(riskPrefer) 范围是2-7
        'upper_limits': [[1, 0.2], [0.6, 0.4], [0, 0.6], [0, 0.2], [0, 0.4]],
        'fluctuation': 'default',  # 风险约束  日波动率限制0.0000000004#
    }
    recommendDate = time.strftime('%Y-%m-%d', time.localtime(time.time()))
    userParamJson['recommendDate'] = recommendDate
    userParamJson['businessCode'] = "JD"

    system_params_data = {
        'minbounds': [0, 0, 0, 0, 0],
        'maxbounds': [1, 1, 1, 1, 1],
        'w0': [0.2, 0.2, 0.2, 0.2, 0.2],
        'lowerLimitSwitchMatrix': [[1, 1, 0, 0, 0], [1, 1, 1, 0, 0], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]],
        # 资产开关矩阵
        'upper_limits': [[1, 0.2], [0.6, 0.4], [0, 0.6], [0, 0.2], [0, 0.4]],
        'least_invest_amount': [0, 0, 0, 0, 0],
        'lambda_mkt': 1,
        'categoryLimitCoefficients': [[-5000, 2000], [-4000, 3000], [-2000, 5000], [3000, 10000], [5000, 12000]],
        'business_info': [{'indexCode': 'I_CN6112_CNI', 'categoryCode': '001', 'order': 1},
                          {'indexCode': 'I_H11001_CSI', 'categoryCode': '002', 'order': 2},
                          {'indexCode': 'I_000300_SH', 'categoryCode': '003', 'order': 3},
                          {'indexCode': 'I_AUM', 'categoryCode': '004', 'order': 4},
                          {'indexCode': 'I_SPX_GI', 'categoryCode': '005', 'order': 5}],
        'point_weightP': view_weight_P,
        'confidenceLC': view_confidence,
        'pointQ': view_Q,
        'historicalOdds': tau_odds,
        'sigema': covariance_matrix,
        'omiga_mkt': market_weights
    }

    json_str = copy.deepcopy(system_params_data)
    json_str.update(userParamJson)  ##叠加用户参数，如果key相同则覆盖
    #
    # business_info = [{"categoryCode": "001", "indexCode": "I_CN6112_CNI", "order": 1},
    #                  {"categoryCode": "002", "indexCode": "I_H11001_CSI", "order": 2},
    #                  {"categoryCode": "003", "indexCode": "I_000300_SH", "order": 3},
    #                  {"categoryCode": "004", "indexCode": "I_AUM", "order": 4},
    #                  {"categoryCode": "005", "indexCode": "I_SPX_GI", "order": 5}]
    #
    # json_str["business_info"] = business_info

    bl = BL2.BlackLitterman(json_str=json_str)
    # bl.fun(json_str['w0'])
    resultData = bl.optimize()
    print(resultData)


if __name__ == '__main__':
    pass
    Run_BL1()
    Run_BL2()